home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / asmsrc / thesource-7.lha / Source / DefFunc.lha / DefFunc / dfctree.c < prev    next >
C/C++ Source or Header  |  1993-12-14  |  4KB  |  200 lines

  1. /*********************************************************
  2.  *
  3.  *    Copyright (c) 1993  Ke Jin
  4.  *
  5.  *    Permission to use, copy, modify, and distribute
  6.  *    this software and its documentation without fee
  7.  *    is granted, provided that the author's name and
  8.  *    this copyright notice are retained.
  9.  *
  10.  * -----------------------------------------------------
  11.  *
  12.  *    dfctree.c -- defunc low level module
  13.  *
  14.  *    public  function : exparse();
  15.  *                       evaluate();
  16.  *                       reduce();
  17.  *     
  18.  *********************************************************/
  19.  
  20. #include <stdio.h>
  21. #include "dfctree.h"
  22.  
  23. #ifdef __cplusplus
  24.   extern "C" {    /* for c++ */
  25. #endif
  26.  
  27. #if NeedFunctionPrototypes
  28.   extern yyinit(char* expression);
  29.   extern int yyparse(void);
  30. #else
  31.   extern yyinit();
  32.   extern int yyparse();
  33. #endif
  34.  
  35. #define ltree  reduce(tree+tree->left-i,  tree->left)
  36. #define rtree  reduce(tree+tree->right-i, tree->right)
  37. #define trval  tree->content.value
  38. #define ltrval ltree->content.value
  39. #define rtrval rtree->content.value
  40.  
  41. #if NeedFunctionPrototypes
  42.   Node* reduce(Node* tree, int i)
  43. #else
  44.   Node* reduce(tree, i)
  45.   Node* tree;
  46.   int   i;
  47. #endif
  48. /* constant folding. i is the shift relative to root 
  49.  * reduce tree still in original memory address. the
  50.  * root of the tree be returned */
  51.     if(tree == 0) return 0;
  52.  
  53.     switch(tree->type)
  54.     {
  55.     case const_node:
  56.     case arg_node:
  57.              break;
  58.  
  59.     case simplex_fnct_node:
  60.          if(rtree->type==const_node)
  61.          {
  62.          tree->type = const_node;
  63.          trval = (tree->content.fnctptr)(rtrval);
  64.              }
  65.          break;
  66.  
  67.         case duplex_fnct_node:
  68.          if((ltree->type==const_node)&&(rtree->type==const_node))
  69.          {
  70.          tree->type = const_node;
  71.          trval = (tree->content.fnctptr)(ltrval, rtrval);
  72.              }
  73.          break;
  74.  
  75.         case unary_op_node:
  76.           if(rtree->type==const_node)
  77.          {
  78.           tree->type = const_node;
  79.          switch(tree->content.op)
  80.          {
  81.              case op_neg: trval = -rtrval; break;
  82.  
  83.              default: break;
  84.                  }
  85.              }
  86.          break;
  87.  
  88.         case binary_op_node:
  89.          if(rtree->type==const_node&&tree->content.op==op_div)
  90.          {
  91.          tree->content.op=op_mul;
  92.          rtree->content.value = 1.0/(rtree->content.value);
  93.              }
  94.  
  95.          if(ltree->type==const_node&&rtree->type==const_node)
  96.          {
  97.          tree->type = const_node;
  98.          switch(tree->content.op)
  99.          {
  100.              case op_sum: trval = ltrval+rtrval; break;
  101.              case op_sub: trval = ltrval-rtrval; break;
  102.              case op_mul: trval = ltrval*rtrval; break;
  103.              case op_div: trval = ltrval/rtrval; break; 
  104.  
  105.              default: break;
  106.                  }
  107.              }
  108.              break;
  109.  
  110.         default: break;
  111.     }  
  112.  
  113.     return tree;
  114. }; 
  115.  
  116. #if NeedFunctionPrototype
  117.   int exparse(char* expression)
  118. #else
  119.   int exparse(expression)
  120.   char* expression;
  121. #endif
  122. {
  123.     yyinit(expression);  /* initial the parser */
  124.  
  125.     return yyparse();    /* on success, return 0 or tree size
  126.               * on error  , return -1 */
  127. };
  128.  
  129. #define lval evaluate(tree+tree->left-i,  tree->left , x, y)
  130. #define rval evaluate(tree+tree->right-i, tree->right, x, y) 
  131.  
  132. #if NeedFunctionPrototype
  133.   double evaluate(Node* tree, int i, double x, double y)
  134. #else
  135.   double evaluate(tree, i, x, y) 
  136.   Node*  tree;
  137.   int    i;
  138.   double x, y;
  139. #endif
  140. /* evaluate a parse tree. i is the shift relative to root */
  141. {
  142.     if(tree == 0) 
  143.     {
  144.     fprintf(stderr, "Null parse tree\n");
  145.         exit(1) ;
  146.     }
  147.  
  148.     switch (tree->type) 
  149.     {
  150.     case const_node:
  151.          return tree->content.value;
  152.  
  153.         case arg_node:
  154.          switch(tree->content.argidx)
  155.          {
  156.          case 1: return x;
  157.          case 2: return y;
  158.          default: exit(1);
  159.              }
  160.          break;
  161.  
  162.     case simplex_fnct_node:
  163.          return (tree->content.fnctptr)(rval);
  164.  
  165.         case duplex_fnct_node:
  166.          return (tree->content.fnctptr)(lval, rval);
  167.  
  168.         case unary_op_node:
  169.          switch(tree->content.op)
  170.          {
  171.         case op_neg: return -rval;
  172.  
  173.         default: break;
  174.              }
  175.          break;
  176.  
  177.         case binary_op_node:
  178.              switch(tree->content.op)
  179.          {
  180.         case op_sum: return lval + rval; 
  181.                 case op_sub: return lval - rval;
  182.         case op_mul: return lval * rval;
  183.         case op_div: return lval / rval;
  184.  
  185.         default: break;
  186.              }
  187.          break;
  188.  
  189.         default:
  190.          exit(1) ;   /* something wrong */
  191.     }
  192.  
  193.     return 0; /* turn off the warning of lint */
  194. };
  195.  
  196. #ifdef __cplusplus
  197.   }    /* end for c++ */
  198. #endif
  199.